/*
 ============================================================================
 Name        : poll_foobar.c
 Author      : liu.sh
 Version     :
 Copyright   : Your copyright notice
 Description : Hello World in C, Ansi-style
 ============================================================================
 */

#include <stdio.h>
#include <stdlib.h>
#include <sys/poll.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>


int setnonblocking(int sock)
{
	int opts;
	opts=fcntl(sock,F_GETFL);
	if(opts<0)
	{
		printf("[%d][%s]\n", errno, strerror(errno));
		return(-1);
	}
	opts = opts|O_NONBLOCK;
	if(fcntl(sock,F_SETFL,opts)<0)
	{
		printf("[%d][%s]\n", errno, strerror(errno));
		return(-2);
	}

	return(0);
}


int main(void) {
	int ret = 0;
	int i = 0;
	int stat = 0;
	int listener = 0;
	int addrlen = 0;
	int cli_sock = 0;
	nfds_t nfds = 200;
	struct pollfd *fds = NULL;
	struct sockaddr_in my_addr, their_addr;


	fds = calloc(nfds, sizeof(struct pollfd));
	if(fds == NULL)
	{
		printf("fds calloc faild\n");
		stat = 1;
		goto err;
	}
	
	for(i = 0;i < nfds; i++)
	{
		fds[i].fd = -1;
	}

	printf( "run as server\n");

	//create listen socket
	if((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1)
	{
		printf( "[%d][%s]\n", errno, strerror(errno));
		stat = 2;
		goto err;
	}

	//set non-block
	//setnonblocking(listener);

	//set addr
	my_addr.sin_family = PF_INET;
	my_addr.sin_port = htons(21111);
	my_addr.sin_addr.s_addr = htons(INADDR_ANY);

	//bind
	if (bind(listener, (struct sockaddr *) &my_addr, sizeof(struct sockaddr)) == -1)
	{
	  printf( "[%d][%s]\n", errno, strerror(errno));
		close(listener);
		stat = 3;
		goto err;
	}

	//listen
	if (listen(listener, 1) == -1)
	{
	  printf( "[%d][%s]\n", errno, strerror(errno));
		close(listener);
		stat = 4;
		goto err;
	}

	fds[0].fd = listener;
	fds[0].events = POLLIN;

	while(1)
	{
		ret = poll(fds, nfds, -1);
		printf("ret = [%d]\n", ret);
		if(ret < 0)
		{
			perror("poll is failed");
		}
		if(fds[0].revents & POLLIN)
		{
			cli_sock = accept(listener, (struct sockaddr *) &their_addr, &addrlen);
			printf("source addr is %s:%d new socket is:%d", inet_ntoa(their_addr.sin_addr), ntohs(their_addr.sin_port), cli_sock);
			close(cli_sock);
		}
	}
	return EXIT_SUCCESS;
err:
	if(stat > 1)
	{
		free(fds);
	}
	exit(stat);
}
